﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;

namespace Cmd.Internal
{
	internal static class RawParser
	{
		internal static string[] CmdDelimiters = new string[] { "/", "-" };
		internal static string[] ValueDelimiters = new string[] { ":", "=" };
		internal static string[] ValueRestrainDelimiters = new string[] { "\"", "'" };

		internal static HashSet<KeyValuePair<string, string>> ParseRawValues(string cmdLineArgs)
		{
			HashSet<KeyValuePair<string, string>> dct = new HashSet<KeyValuePair<string, string>>();
			int i = 0;
			string arg = string.Empty;
			string val = string.Empty;
			bool isValue = false;
			bool isMiddle = false;
			while (i < cmdLineArgs.Length)
			{
				char c = cmdLineArgs[i];

				if (!isMiddle && ValueDelimiters.Contains(c.ToString()))
				{
					isValue = true;
				}
				if (c == '"' && !isMiddle)
				{
					isMiddle = true;
				}
				else if (c == '"' && isMiddle)
				{
					isMiddle = false;
				}

				if (isValue)
				{
					val += cmdLineArgs[i];
				}
				else
				{
					arg += cmdLineArgs[i];
				}

				if (c == ' ' && !isMiddle)
				{
					string[] valueList = ParseArgValuePair(arg, val);
					KeyValuePair<string, string> kv = new KeyValuePair<string, string>(valueList[0], valueList[1]);
					if (!dct.Contains(kv))
					{
						dct.Add(kv);
					}
					arg = string.Empty;
					val = string.Empty;
					isValue = false;
					isMiddle = false;
					i++;
					continue;
				}
				else if (i + 1 == cmdLineArgs.Length)
				{
					string[] valueList = ParseArgValuePair(arg, val);
					KeyValuePair<string, string> kv = new KeyValuePair<string, string>(valueList[0], valueList[1]);
					if (!dct.Contains(kv))
					{
						dct.Add(kv);
					}
				}
				i++;
			}

			i = 0;
			while (i < dct.Count)
			{
				if (string.IsNullOrWhiteSpace(dct.ElementAt(i).Key))
				{
					dct.Remove(dct.ElementAt(i));
					continue;
				}
				i++;
			}

			return dct;
		}

		private static string[] ParseArgValuePair(string arg, string value)
		{
			arg = arg.Trim();
			value = value.Trim();
			if (!string.IsNullOrEmpty(arg))
			{
				while (arg.Length > 0 && CmdDelimiters.Contains(arg[0].ToString()))
				{
					arg = arg.Substring(1);
				}
			}

			if (!string.IsNullOrEmpty(value))
			{
				while (value.Length > 0 && ValueDelimiters.Contains(value[0].ToString()))
				{
					value = value.Substring(1);
				}
				while (value.Length > 0 && ValueRestrainDelimiters.Contains(value[value.Length - 1].ToString()))
				{
					value = value.Substring(0, value.Length - 1);
				}
				while (value.Length > 0 && ValueRestrainDelimiters.Contains(value[0].ToString()))
				{
					value = value.Substring(1);
				}

			}
			return new string[] { arg, value };
		}

		internal static string ParseRawArguments(string command)
		{
			string processFilename = Path.GetFileNameWithoutExtension(Process.GetCurrentProcess().MainModule.FileName);
			string args = string.Empty;
			int idx = command.ToLower().IndexOf(processFilename.ToLower());
			if (idx >= 0)
			{
				idx += processFilename.Length;
				int startIndex = idx;
				while (idx < command.Length && command[idx] != ' ')
				{
					idx++;
				}
				if (idx < command.Length)
				{
					args = command.Substring(idx);
				}
			}
            return args;
		}
	}
}
